/**
 * \file util.c
 * \author Davide Gessa
 * \date 10-12-09
 */
#include <util.h>
#include <task/task.h>
#include <task/service.h>
#include <task/message.h>
#include <types.h>
#include <main.h>
#include <video.h>

/**
 * Restituisce le info del sistema
 * 
 * \param ki puntatore ad una struttura sysinfo
 */
void sysinfo_get(sysinfo_t *ki)
{
	strcpy(ki->name, NAME);
	strcpy(ki->ver, VER);
	strcpy(ki->rev, REV);
	strcpy(ki->date, __DATE__);
	strcpy(ki->time, __TIME__);
	strcpy(ki->arch, ARCH);
}


/*
 * Task di prova
 */
int task1(int argc, char **argv)
{
	while(1) video_puts("1");
}

int task2(int argc, char **argv)
{
	while(1) video_puts("2");
}


/**
 * Visualizza la memoria usata rispetto a quella totale
 */
void show_used_memory()
{
	video_puts_colored(VIDEO_HI_BLUE_BLACK, "\t-> ");		
	video_puts("Memory state: ");
	video_putint(mm_get_used_mem());
	video_puts("/");
	video_putint(mm_get_total_mem());
	video_puts(" (kb)\n");
}


/**
 * Visualizza la lista dei servizi
 */
void show_service_list()
{
	service_t *t = service_list;
	
	video_puts_colored(VIDEO_HI_BLUE_BLACK, "\t-> ");
	video_puts("Service list: \n");
	
	while(t != NULL)
	{
		video_puts_colored(VIDEO_HI_BLUE_BLACK, "\t\t-> ");
		video_puts(t->name);
		video_puts(" (");
		video_putint(t->pid);
		video_puts(")\n");
		
		t = t->next;
	}
}

/**
 * Visualizza la lista dei task
 */
void show_task_list()
{
	task_t *t = task_list;
	
	video_puts_colored(VIDEO_HI_BLUE_BLACK, "\t-> ");
	video_puts("Task List: \n");
	while(t != NULL)
	{
		video_puts_colored(VIDEO_HI_BLUE_BLACK, "\t\t-> ");
		video_puts(t->name);
		video_puts(" (");
		video_putint(t->pid);
		video_puts(")\n");
		t = t->next;
	}
}


/**
 * Visualizza la lista dei messaggi di un task
 * 
 * \param pid task da analizzare
 */
void show_task_message_list(pid_t pid)
{
	if(task_get_from_pid(pid) == NULL) return;
	
	message_t *msg = task_get_from_pid(pid)->msg_start;
	
	
	video_puts_colored(VIDEO_HI_BLUE_BLACK, "\t-> ");
	video_puts("Msg List of ");
	video_putint(pid);
	video_puts("\n");
		
	while(msg != NULL)
	{
		video_puts_colored(VIDEO_HI_BLUE_BLACK, "\t\t-> ");
		video_puts("Msg: ");
		video_puts(msg->data);
		video_puts("\n");
		
		msg = msg->next;
	}

}

	
/**
 * Rilascia la lunghezza di una stringa
 * 
 * \param str stringa da analizzare
 * \return lunghezza stringa
 */
size_t strlen(char *str)
{
	size_t x = 0;

	while(*str++!='\0') x++;
		
	return x;
}


/**
 * Copia una stringa in un altra
 * 
 * \param str1 stringa destinazione
 * \param str2 stringa sorgente
 */
void strcpy(char *str1, char *str2)
{
	while(*str2 != '\0')
	{
		*str1 = *str2;
		str1++; str2++;
	}
	*str1 = '\0';
}


/**
 * Unisce due stringhe
 * 
 * \param str1 stringa destinazione
 * \param str2 stringa sorgente
 */
void strcat(char *str1, char *str2)
{
	while(*str1 != '\0') str1++;
	
	while(*str2 != '\0')
	{
		*str1 = *str2;
		str1++;
		str2++;
	}
	*str1 = '\0';
}


/**
 * Confronta la stringa 1 con la stringa 2
 * 
 * \param str1 stringa 1
 * \param str2 stringa 2
 */
int strcmp(char *s1, char *s2)
{	
	while(1)
	{
		if(*s1 != *s2) return 1;
		else if(*s1 == '\0' && *s2 == '\0') return 0;
		s1++; 
		s2++;
	}
}



/**
 * Trasforma un intero in una stringa restituendo un puntatore
 * 
 * \param num numero da convertire
 * \return stringa del numero
 */
char *itoa(int num)
{
	static char buff[10];
	char *str = buff + 9;
	int j = num;
	*str-- = 0;

	// Divide per 10 e mette il resto nella stringa, finche' non finisce il numero
	do 
		*str-- = num % 10 + '0';  
	while ((num = num / 10));

	// Se il numero e' negativo, mette il -
	if(j < 0)
		*str-- = '-';

	// Restituisce il puntatore
	return ++str;
}



/**
 * Riempie un area di memoria di lunghezza len con il dato data
 * 
 * \param s area di memoria da impostare
 * \param c dato da inserire nell'area
 * \param n grandezza dell'area
 */
void *memset(uint8_t *s, uint8_t c, size_t n)
{
	size_t i;
	
	for (i = 0; i < n; i++, s++)
		*s = c;
	
	return s;
}


/**
 * Trasforma un int a 8 bit da bcd a binario
 * 
 * \param bcd numero bcd
 * \return numero binario
 */
uint8_t bcd2bin(uint8_t bcd)
{
    return ((bcd >> 4) * 10) + (bcd & 0x0F);
}
